/**
**************************************************************************************
*Palisma - Secrets of the Illuminati is an open-source 2D RPG                        *
*Copyright (C) 2006, Tony Sparks                                                     *
*                                                                                    *
*This library is free software; you can redistribute it and/or                       *
*modify it under the terms of the GNU Lesser General Public                          *
*License as published by the Free Software Foundation; either                        *
*version 2.1 of the License, or (at your option) any later version.                  *
*                                                                                    *
*This library is distributed in the hope that it will be useful,                     *
*but WITHOUT ANY WARRANTY; without even the implied warranty of                      *
*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU                   *
*Lesser General Public License for more details.                                     *
*                                                                                    *
*You should have received a copy of the GNU Lesser General Public                    *
*License along with this library; if not, write to the Free Software                 *
*Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA      *
**************************************************************************************
*/
#include "StdAfx.h"
#include "ViewManager.h"
#include "entityview.h"
#include "../shared/QuadTree.h"
#include <algorithm>

#include "../kernel.h"

extern Kernel* g_kernel;

/*-------------------------------------------
    Sorting 
--------------------------------------------*/
// Sort based off of Y coord, the lower the Y, draw higher
 bool ViewSort(const EntityView* start, const EntityView* end) 
 {
    if ( start->m_owner->m_flags & EF_DRAWOVER && end->m_owner->m_flags & EF_DRAWOVER )
        return (start->m_owner->m_position.y < end->m_owner->m_position.y);

    if ( !(start->m_owner->m_flags & EF_DRAWOVER) && !(end->m_owner->m_flags & EF_DRAWOVER) )
        return (start->m_owner->m_position.y < end->m_owner->m_position.y);

    return (start->m_owner->m_flags & EF_DRAWOVER);

 }



ViewManager* ViewManager::instance = new ViewManager;

ViewManager::ViewManager(void)
{
}

EntityView* ViewManager::CreateView( IEntity* ent ) 
{ 
    // create our view
    EntityView* view = new EntityView(ent);
    view->SetRefID ( ent->GetID() ); // just to make sure it's set
    Model* model = new Model;
    view->SetModel( model );
    m_views/*[ ent->GetID()] = view;/*/.push_back( view );
    return view;
}

ViewManager::~ViewManager(void)
{
    type_views::iterator it = m_views.begin();
    // render each object
    for( ; it != m_views.end(); ++it )
    {
        //if( it->second )
        //    delete it->second;
        if( (*it) )
            delete (*it);
    }
}

/** Remove the view */
void ViewManager::RemoveView(int id) { 
    type_views::iterator it = m_views.begin();
    // render each object
    for( ; it != m_views.end(); ++it )
    {
        if( (*it)/*it->second*/->GetRefID() == id )
        {
            g_kernel->LPrintf( "--Deleting from ViewManager:: Releasing %d bytes", sizeof( (*it) ) );
            delete (*it); // it->second;
            m_views.erase( it );
            return;
        }
    } 
};

/** Update each view */
void ViewManager::Update(IRender *r, ICamera* cam)
{
    // current time
    float deltaTimeInMSec = g_kernel->GetFrameTime();

    //if ( quadTree )
    //{
    //    std::vector<IEntity*> visibleEntities;
    //    ICamera* cam = g_kernel->GetRenderer()->GetCamera(0);
    //    quadTree->GetObjects( cam->GetViewPort(), visibleEntities );

    //    size_t entSize = visibleEntities.size();
    //    std::vector<EntityView*> viewList;
    //    for(int i = 0; i < entSize; ++i )
    //    {
    //        EntityView* view = m_views[ visibleEntities[i]->GetID() ];
    //        if ( view )
    //        {
    //            viewList.push_back( view );
    //        }
    //    }
    //    // sort out the Y values for proper drawing
    //    std::sort( viewList.begin(), viewList.end(), ViewSort );
    //    size_t viewSize = viewList.size();
    //    for(int i =0;i< viewSize; ++i )
    //    {
    //        EntityView* view = viewList[i];
    //        // update the view
    //        view->Update(time);
    //        // now draw the view
    //        view->Render( r );
    //    }

    //}
    // sort out the Y values for proper drawing
    std::sort( m_views.begin(), m_views.end(), ViewSort );
    type_views::iterator it = m_views.begin();
    // render each object
    for( ; it != m_views.end(); ++it )
    {
        EntityView* view = (*it);//it->second;
        if ( cam->Contains( view->m_owner->GetBounds() ) )//view->m_owner->m_world.x+32, view->m_owner->m_world.y+32 ) )
        {
            // update the view
            view->Update( deltaTimeInMSec );
            // now draw the view
            view->Render( r, cam );
            
        }
    }
}